package com.chaos.auth.service;

import com.chaos.auth.api.dto.MenuDto;
import com.chaos.auth.api.dto.auth.RbacMenuChildrenDto;
import com.chaos.framework.model.dto.ID;
import com.chaos.framework.model.dto.IDS;
import com.chaos.framework.model.dto.page.PageList;
import com.chaos.framework.model.dto.page.PageQueryDto;
import com.chaos.framework.model.entity.Table;
import com.chaos.framework.model.helper.ConvertHelper;
import com.chaos.framework.model.helper.PageHelper;
import com.chaos.auth.entity.RbacMenu;
import com.chaos.auth.api.data.RbacMenuData;
import com.chaos.auth.mapper.RbacMenuMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Jacky.Cui
 * @since 2024-11-13
 */
@Slf4j
@Component
public class RbacMenuService extends ServiceImpl<RbacMenuMapper, RbacMenu> {

    public ID insertModel(RbacMenuData data) {
        RbacMenu entity = ConvertHelper.convert(data, RbacMenu.class);
        return save(entity) ? new ID(entity.getId()) : null;
    }

    public boolean deleteModel(ID data) {
        return removeById(data.getId());
    }

    public boolean updateModelByID(RbacMenuData data) {
        RbacMenu entity = ConvertHelper.convert(data, RbacMenu.class);
        return update(entity, new UpdateWrapper<RbacMenu>().eq(Table.ID, data.getId()));
    }

    public RbacMenuData selectByID(ID data) {
        return ConvertHelper.convert(getOne(new QueryWrapper<RbacMenu>().eq(Table.ID, data.getId())), RbacMenuData.class);
    }

    public List<RbacMenuData> selectByData(RbacMenuData data) {
        QueryWrapper<RbacMenu> query = new QueryWrapper<>();
        query.orderByDesc(Table.ID);
        return ConvertHelper.convert(list(query), RbacMenuData.class);
    }

    public List<RbacMenuChildrenDto> selectByData(RbacMenuChildrenDto data) {
        QueryWrapper<RbacMenu> query = new QueryWrapper<>();
        query.orderByDesc(Table.ID);
        return ConvertHelper.convert(list(query), RbacMenuChildrenDto.class);
    }

    public PageList<RbacMenuData> selectByPage(PageQueryDto<RbacMenuData> pageData) {
        QueryWrapper<RbacMenu> query = new QueryWrapper<>();
        query.lambda().eq(!StringUtils.isBlank(pageData.getData().getName()), RbacMenu::getName, pageData.getData().getName()).eq(!StringUtils.isBlank(pageData.getData().getPath()), RbacMenu::getPath, pageData.getData().getPath());
        query.orderByAsc(Table.SORT);
        return PageHelper.pageList(page(PageHelper.page(pageData), query), RbacMenuData.class);
    }

    public List<RbacMenuData> selectByIds(IDS ids) {
        QueryWrapper<RbacMenu> query = new QueryWrapper<>();
        query.lambda().in(RbacMenu::getId, ids.getIds());
        query.orderByDesc(Table.ID);
        return ConvertHelper.convert(list(query), RbacMenuData.class);
    }


    // 构建递归菜单
    public List<RbacMenuChildrenDto> buildMenuTree(List<RbacMenuChildrenDto> menuList) {
        Map<Long, RbacMenuChildrenDto> menuMap = new HashMap<>();
        List<RbacMenuChildrenDto> rootMenus = new ArrayList<>();

        for (RbacMenuChildrenDto menu : menuList) {
            menuMap.put(menu.getId(), menu);
        }

        for (RbacMenuChildrenDto menu : menuList) {
            Long parentId = menu.getParentId();
            if (parentId == null || parentId == 0) {
                rootMenus.add(menu);
            } else {
                RbacMenuChildrenDto parentMenu = menuMap.get(parentId);
                if (parentMenu != null) {
                    if (parentMenu.getChildren() == null) {
                        parentMenu.setChildren(new ArrayList<>());
                    }
                    parentMenu.getChildren().add(menu);
                }
            }
        }

        return rootMenus;
    }
}
